//String Name = File.getName();  //获得文件或文件夹的名称：  
//String parentPath = File.getParent();  //获得文件或文件夹的父目录  
//String path = File.getAbsoultePath();//绝对路经  
//String path = File.getPath();//相对路经   
//File.createNewFile();//建立文件    
//File.mkDir(); //建立文件夹    
//File.isDirectory(); //判断是文件或文件夹  
//File[] files = File.listFiles();  //列出文件夹下的所有文件和文件夹名  
//File.renameTo(dest);  //修改文件夹和文件名  
//File.delete();  //删除文件夹或文件  


package com.practices2.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;

public class FileUtil {

	public static String SDcardPath = Environment.getExternalStorageDirectory().getPath();
	public static String projectName = "com.practices.util";
	public static String root_path = SDcardPath + File.separator + projectName + File.separator;
	public static String temp_path = root_path + "temp" + File.separator;

	public void initFileDir() {
		if (TextUtils.isEmpty(SDcardPath)) {
		}
		if (isMounted()) {
			File file = new File(root_path);
		}
	}

	public static String getSDcardPath() {
		return SDcardPath;
	}

	public static String getroot_path() {
		return root_path;
	}

	public static String gettemp_path() {
		return temp_path;
	}

	public boolean isMounted() {
		return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
	}

	// 保存bitmap承PNG文件
	public static boolean saveBitmapToFile(Bitmap bitmap, String Path) throws IOException {
		if (bitmap == null) {
			return false;
		}
		BufferedOutputStream bos = null;
		try {
			File mPicture = new File(Path);
			if (mPicture.exists()) {
				mPicture.delete();
			}
			bos = new BufferedOutputStream(new FileOutputStream(mPicture));
			bitmap.compress(CompressFormat.PNG, 100, bos);
			bos.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} finally {
			if (bos != null) {
				bos.close();
			}
		}
		return true;
	}

	// 单位bytes
	public static long getAvailaleSize(String path) {

		StatFs stat = new StatFs(path);
		/* 获取block的SIZE */
		long blockSize = stat.getBlockSize();
		/* 空闲的Block的数量 */
		long availableBlocks = stat.getAvailableBlocks();
		/* 返回bit大小值 */
		return (availableBlocks * blockSize); // MIB单位
		// (availableBlocks * blockSize)/1024 KIB 单位
		// (availableBlocks * blockSize)/1024 /1024 MIB单位
	}

	public static String parseFileName(String absPath) {
		int dn = absPath.lastIndexOf(File.separator);
		if (dn != -1) {
			String name = absPath.substring(dn + 1);
			return name;
		} else {
			return absPath;
		}
	}

	// gzip 压缩字符串
	public static byte[] gzipCompress(byte[] buf) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPOutputStream gos = new GZIPOutputStream(bos);
		gos.write(buf);
		gos.close();
		return bos.toByteArray();
	}

	public static byte[] GzipUnCompress(byte[] buf) throws IOException {
		ByteArrayInputStream bis = new ByteArrayInputStream(buf);
		GZIPInputStream gis = new GZIPInputStream(bis);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] buff = new byte[256];
		int count;
		while ((count = gis.read(buff)) != -1) {
			bos.write(buff, 0, count);
		}
		// toString()使用平台默认编码，也可以显式的指定如toString("UTF-8")
		return bos.toByteArray();

	}

	public static boolean rename(String src, String dest) {
		if (src != null && dest != null) {
			File srcFile = new File(src);
			return srcFile.renameTo(new File(dest));
		} else {
			return false;
		}
	}

	public static boolean isFileExist(String path) {
		if (TextUtils.isEmpty(path)) {
			return false;
		}
		File file = new File(path);
		return (file.exists());
	}

	public static boolean deleteFile(String path) {
		boolean isDeleted = false;
		File file = new File(path);

		if (file.exists() && file.isFile()) {
			isDeleted = file.delete();
		}
		return isDeleted;
	}

	public static void deleteDirectory(String dirPath) {
		File dirFile = new File(dirPath);
		if (dirFile != null && dirFile.exists()) {
			deleteDirectory(dirFile);
		}
	}

	public static void deleteDirectory(File dirFile) {
		File[] files = dirFile.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				deleteDirectory(file);
			} else if (file.isFile()) {
				file.delete();
			}
		}
		dirFile.delete();
	}

	/**
	 * 计算文件夹大小
	 * 
	 * @param dir
	 * @return
	 */
	public static long getDirSize(File dir) {
		if (dir == null) {
			return 0;
		}
		if (!dir.isDirectory()) {
			return 0;
		}
		long dirSize = 0;
		File[] files = dir.listFiles();
		for (File file : files) {
			if (file.isFile()) {
				dirSize += file.length();
			} else if (file.isDirectory()) {
				dirSize += file.length();
				dirSize += getDirSize(file); // 如果遇到目录则通过递归调用继续统计
			}
		}
		return dirSize;
	}

	// 读取指定文件的内容那个，返回byte数组
	public static byte[] readFileAsBytes(String path) throws OutOfMemoryError {
		FileInputStream fis = null;
		try {
			File file = new File(path);
			fis = new FileInputStream(file);
			byte[] buf = new byte[(int) file.length()];
			fis.read(buf);
			return buf;
		} catch (Exception e) {
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return null;
	}

	public static String readFileAsString(String path, String charset) throws UnsupportedEncodingException {
		byte[] buff = readFileAsBytes(path);
		if (buff != null) {
			return new String(buff, charset);
		}
		return null;
	}

	public static void saveFile(String path, byte[] buf) {
		saveFile(path, buf, 0, buf.length);
	}

	public static void saveFile(String path, byte[] buf, int offset, int count) {
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(path);
			fos.write(buf, offset, count);
		} catch (Exception e) {

		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	public static int bytesToInt(byte[] buf, int offset) {
		return ((buf[offset] & 0xFF) << 24) | ((buf[offset + 1] & 0xFF) << 16) | ((buf[offset + 2] & 0xFF) << 8) | (buf[offset + 3] & 0xFF);
	}

	public static void intToBytes(int value, byte[] buf, int offset) {
		buf[offset] = (byte) (value >> 24);
		buf[offset + 1] = (byte) (value >> 16);
		buf[offset + 2] = (byte) (value >> 8);
		buf[offset + 3] = (byte) value;
	}

	// 删除指定路径下所有txt文件 删除TXT文件
	public void deleteAllTxt(String path) {
		File folder = new File(path);
		String fileName = null;

		if (folder.isDirectory()) {
			// 列出所有文件保存发到File[]
			File[] files = folder.listFiles();

			// 遍历得到的文件信息File[]
			for (File file : files) {
				// 得到文件名然后判断是否带有.txt后缀 有则删除
				fileName = file.getName();
				if (fileName.lastIndexOf(".txt") != -1) {
					file.delete();
				} else {
					System.out.println("没有txt文件或者已被删除");
				}
			}
		} else {
			System.out.println("不能对非文件夹进行操作！！！");
		}
		if (-1 == fileName.lastIndexOf(".txt")) {

			System.out.println("没有txt文件或者已被删除");
		}
	}

	// 删除文件夹
	public void deleteFolder(String path) {
		File Folder = new File(path); // 用File类表示出源文件夹
		File[] Folders = Folder.listFiles(); // 用File类型数组表示文件夹下的文件

		if (Folder.isDirectory()) {

			for (File file : Folders) {
				if (file.isDirectory()) {
					deleteFolder(path + File.separator + file.getName());
				} else {
					// deleteFile(file); //这是个经验 参数类型不匹配 利用类库方法 减少错误
					file.delete(); // delete()删除文件或空文件夹 删除 自己以外的 空子文件夹
				}
			}
			Folder.delete(); // 删除自己 最后一个空文件夹
			// System.out.println("删除成功");

		} else
			System.out.println("不是文件夹或者文件夹不存在！");

	}

	// 以字节为单位 根据源文件和目标文件的路径 复制文件
	// fromPath:源文件路径 toPath：目标文件路径
	public void copyFile(String fromPath, String toPath) {
		// 用File表示出源文件和目标文件
		File fromFile = new File(fromPath);
		File toFile = new File(toPath);

		InputStream is = null;
		OutputStream os = null;

		try {
			// 建立输入输出流 分别连接一个文件
			is = new FileInputStream(fromFile);
			os = new FileOutputStream(toFile);

			int readByte = 0;
			while ((readByte = is.read()) != -1) { // 循环读取和写入
				os.write(readByte); // 才输入到管道而已
				os.flush(); // 真正写入文件
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally { // 释放文件资源
			try {
				if (is != null) {
					is.close();
				}
				if (os != null) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

	// 以自定义缓冲区为单位 根据源文件和目标文件的路径 复制文件：
	public void copyFileWithBuffer(String fromPath, String toPath) {

		// 用File表示出源文件和目标文件
		File fromFile = new File(fromPath);
		File toFile = new File(toPath);

		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		try {
			// 建立输入输出流 分别连接一个文件 用了装饰者设计模式
			bis = new BufferedInputStream(new FileInputStream(fromFile)); // ~~小管子套进大管子
			bos = new BufferedOutputStream(new FileOutputStream(toFile));

			byte[] buf = new byte[102400]; // 100K
			int readLen = 0;
			while ((readLen = bis.read(buf)) != -1) { // 循环读取一个缓冲区并写入
				// System.out.println(readLen);
				bos.write(buf, 0, readLen); // 才输入到管道而已
				bos.flush(); // 真正写入文件
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally { // 释放文件资源
			try {
				if (bis != null | bos != null) {
					bis.close();
					bos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

	public List<String> getFileList(String dirPath) {
		List<String> fileList = new ArrayList<String>();
		File fromFolder = new File(dirPath); // 用File类表示出源文件夹
		if (fromFolder.isDirectory()) {
			File[] fromFolders = fromFolder.listFiles(); // 用File类型数组表示文件夹下的文件
			for (int i = 0; i < fromFolders.length; i++) {
				fileList.add(fromFolders[i].getPath());
			}
			return fileList;
		} else if (fromFolder.isFile()) {
			fileList.add(fromFolder.getPath());
			return fileList;
		}
		return null;
	}

	// 把文件夹复制到指定路径（递归） 复制文件夹
	public void copyFolder(String fromPath, String toPath) {

		File fromFolder = new File(fromPath); // 用File类表示出源文件夹
		File[] fromFolders = fromFolder.listFiles(); // 用File类型数组表示文件夹下的文件

		File toFolder = new File(toPath); // 用File类表示出目标文件夹路径
		toFolder.mkdirs(); // 创建文件夹

		if (fromFolders == null) {
			return;
		} else {
			for (File file : fromFolders) {
				if (file.isDirectory()) {
					copyFolder(fromPath + File.separator + file.getName(), toPath + File.separator + file.getName());
				} else {
					copyFileWithBuffer(fromPath + File.separator + file.getName(), toPath + File.separator + file.getName());
				}
			}
		}
	}

	// 移动文件
	public void removeFile(String fromPath, String toPath) {
		File fromFile = new File(fromPath);
		File tOFile = new File(toPath);
		if (fromFile.isDirectory()) {
			System.out.println("不是文件");
		} else if (fromFile.exists()) {
			copyFileWithBuffer(fromPath, toPath);
			deleteFile(fromPath);
		} else {
			System.out.println("源文件不存在");
		}
	}

	// 移动文件夹
	public void removeFolder(String fromPath, String toPath) {
		File fromFolder = new File(fromPath);
		File tOFolder = new File(toPath);

		if (fromFolder.isDirectory()) {
			copyFolder(fromPath, toPath);
			deleteFolder(fromPath);
		} else {
			System.out.println("不是文件夹");
		}

	}

	// 新建文件 问题 这里面的判断条件
	public void createFile(String newFilePath) {

		File file = new File(newFilePath);
		File baseDir = new File(file.getParent());

		if (file.exists()) { // 是否已经存在
			System.out.println("目标文件已经存在，创建" + newFilePath + "失败");
		} else {
			if (!baseDir.exists()) {
				System.out.println("目标文件父目录不存在，准备创建...");
				file.getParentFile().mkdirs(); // 创建父目录

				try {
					file.createNewFile();

					if (file.exists()) {
						System.out.println("文件创建成功");
					} else {
						System.out.println("文件创建失败");
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

	// 新建文件夹
	public void createNewFolder(String newFilePath) {
		File file = new File(newFilePath);
		File baseDir = new File(file.getParent());

		if (!file.exists()) { // exists()即能判断文件又能判断目录是否存在
			file.mkdirs(); // 创建 文件的 所有上层目录 不创建文件
			if (file.exists()) {
				System.out.println("文件夹创建成功");
			} else {
				System.out.println("文件夹创建失败");
			}

		} else {
			System.out.println("目标文件已经存在，创建" + newFilePath + "失败");
		}
	}

	/**
	 * 返回自定文件或文件夹的大小
	 * 
	 * @param f
	 * @return
	 * @throws Exception
	 */
	public static long getFileSizes(File f) throws Exception {// 取得文件大小
		long s = 0;
		if (f.exists()) {
			FileInputStream fis = null;
			fis = new FileInputStream(f);
			s = fis.available();
		} else {
			f.createNewFile();
			System.out.println("文件不存在");
		}
		return s;
	}

	// 递归
	public static long getFileSize(File f) throws Exception// 取得文件夹大小
	{
		long size = 0;
		File flist[] = f.listFiles();
		for (int i = 0; i < flist.length; i++) {
			if (flist[i].isDirectory()) {
				size = size + getFileSize(flist[i]);
			} else {
				size = size + flist[i].length();
			}
		}
		return size;
	}

	public static String FormetFileSize(long fileS) {// 转换文件大小
		DecimalFormat df = new DecimalFormat("#0.00");
		String fileSizeString = "";
		if (fileS < 1024) {
			fileSizeString = df.format((double) fileS) + "B";
		} else if (fileS < 1048576) {
			fileSizeString = df.format((double) fileS / 1024) + "K";
		} else if (fileS < 1073741824) {
			fileSizeString = df.format((double) fileS / 1048576) + "M";
		} else {
			fileSizeString = df.format((double) fileS / 1073741824) + "G";
		}
		return fileSizeString;
	}

	public static long getlist(File f) {// 递归求取目录文件个数
		long size = 0;
		File flist[] = f.listFiles();
		size = flist.length;
		for (int i = 0; i < flist.length; i++) {
			if (flist[i].isDirectory()) {
				size = size + getlist(flist[i]);
				size--;
			}
		}
		return size;
	}

	/**
	 * Description: 获取属性配置文件
	 * 
	 * @param path
	 *            资源文件路径
	 * @return Properties Object
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static Properties getProperties(String path) throws FileNotFoundException, IOException {
		Properties props = null;
		File file = new File(path);
		if (file.exists() && file.isFile()) {
			props = new Properties();
			props.load(new FileInputStream(file));
		} else {
			System.out.println(file.toString() + "不存在！");
		}
		return props;
	}

	/**
	 * Description: 从属性文件获取值
	 * 
	 * @param props
	 *            Properties Object
	 * @param key
	 * @return 通过key匹配到的value
	 */
	public static String getValue(Properties props, String key, String encod) {
		String result = "";
		String en = "";
		String localEN = System.getProperty("file.encoding");
		if (encod != null && !encod.equals("")) {
			en = encod;
		} else {
			en = localEN;
		}
		try {
			key = new String(key.getBytes(en), "ISO-8859-1");
			result = props.getProperty(key);
			if (!result.equals("")) {
				result = new String(result.getBytes("ISO-8859-1"), en);
			}
		} catch (Exception e) {
		} finally {
			if (result == null)
				result = "";
			return result;
		}
	}

	public static String getValue(Properties props, String key) {
		return getValue(props, key, "");
	}

	/**
	 * 采用Properties类取得属性文件对应值
	 * 
	 * @parampropertiesFileNameproperties文件名，如a.properties
	 * @parampropertyName属性名
	 * @return根据属性名得到的属性值，如没有返回""
	 */
	public static String getValueByPropertyName(String propertiesFileName, String propertyName) {
		String s = "";
		Properties p = new Properties();// 加载属性文件读取类
		FileInputStream in;
		try {
			// propertiesFileName如test.properties
			in = new FileInputStream(propertiesFileName);// 以流的形式读入属性文件
			p.load(in);// 属性文件将该流加入的可被读取的属性中
			in.close();// 读完了关闭
			s = p.getProperty(propertyName);// 取得对应的属性值
		} catch (Exception e) {
			e.printStackTrace();
		}
		return s;
	}

	/**
	 * 采用ResourceBundel类取得属性文件对应值，这个只能够读取，不可以更改及写新的属性
	 * 
	 * @parampropertiesFileNameWithoutPostfixproperties文件名，不带后缀
	 * @parampropertyName属性名
	 * @return根据属性名得到的属性值，如没有返回""
	 */
	public static String getValueByPropertyName_(String propertiesFileNameWithoutPostfix, String propertyName) {
		String s = "";
		// 如属性文件是test.properties，那此时propertiesFileNameWithoutPostfix的值就是test
		ResourceBundle bundel = ResourceBundle.getBundle(propertiesFileNameWithoutPostfix);
		s = bundel.getString(propertyName);
		return s;
	}

	/**
	 * 更改属性文件的值，如果对应的属性不存在，则自动增加该属性
	 * 
	 * @parampropertiesFileNameproperties文件名，如a.properties
	 * @parampropertyName属性名
	 * @parampropertyValue将属性名更改成该属性值
	 * @return是否操作成功
	 */
	public static boolean changeValueByPropertyName(String propertiesFileName, String propertyName, String propertyValue) {
		boolean writeOK = true;
		Properties p = new Properties();
		InputStream in;
		try {

			in = new FileInputStream(propertiesFileName);
			p.load(in);//
			in.close();
			p.setProperty(propertyName, propertyValue);// 设置属性值，如不属性不存在新建
			// p.setProperty("testProperty","testPropertyValue");
			FileOutputStream out = new FileOutputStream(propertiesFileName);// 输出流
			p.store(out, "");// 设置属性头，如不想设置，请把后面一个用""替换掉
			out.flush();// 清空缓存，写入磁盘
			out.close();// 关闭输出流
		} catch (Exception e) {
			e.printStackTrace();
		}
		return writeOK;
	}

	/**
	 * 如果是null，则返回空字符串，如果是非空值则返回该字符串头尾不为空白字符的字符串
	 * 
	 * @param str
	 */
	public static String toNoNullTrimedString(String str) {
		if (str == null) {
			return "";
		}
		return new String(str.trim());
	}

	/**
	 * 如果是null，则返回空字符串，如果是非空值则返回该对象所toString后的字符串
	 * 
	 * @param obj
	 */
	public static String toNoNullString(Object obj) {
		if (obj == null)
			return "";
		return obj.toString();
	}

	/**
	 * 本方法把一个Throwable的StackTrace作为一个字符串输出，以利于对StackTrace的操作。<br />
	 * 通常用于把抛出的Exception转化成字符串进行后续操作。
	 */
	public static String exceptionToStackTrace(Throwable throwable) {
		StringBuffer retu = new StringBuffer();
		StackTraceElement[] traces = throwable.getStackTrace();
		for (StackTraceElement ste : traces) {
			retu.append("\n").append(ste.toString());
		}
		return retu.substring(1);
	}

	/**
	 * 判断一个文件是否为二进制文件
	 */
	public static boolean isBinary(File file) {
		boolean isBinary = false;
		try {
			FileInputStream fin = new FileInputStream(file);
			long len = file.length();
			for (int j = 0; j < (int) len; j++) {
				int t = fin.read();
				if (t < 32 && t != 9 && t != 10 && t != 13) {
					isBinary = true;
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return isBinary;
	}

	/**
	 * 检测sdcard是否可用
	 * 
	 * @return true为可用，否则为不可用
	 */
	public static boolean sdCardIsAvailable() {
		String status = Environment.getExternalStorageState();
		if (!status.equals(Environment.MEDIA_MOUNTED))
			return false;
		return true;
	}

	/**
	 * Checks if there is enough Space on SDCard
	 * 
	 * @param updateSize
	 *            Size to Check
	 * @return True if the Update will fit on SDCard, false if not enough space
	 *         on SDCard Will also return false, if the SDCard is not mounted as
	 *         read/write
	 */
	public static boolean enoughSpaceOnSdCard(long updateSize) {
		String status = Environment.getExternalStorageState();
		if (!status.equals(Environment.MEDIA_MOUNTED))
			return false;
		return (updateSize < getRealSizeOnSdcard());
	}

	/**
	 * get the space is left over on sdcard
	 */
	public static long getRealSizeOnSdcard() {
		File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long availableBlocks = stat.getAvailableBlocks();
		return availableBlocks * blockSize;
	}

	/**
	 * Checks if there is enough Space on phone self
	 * 
	 */
	public static boolean enoughSpaceOnPhone(long updateSize) {
		return getRealSizeOnPhone() > updateSize;
	}

	/**
	 * get the space is left over on phone self
	 */
	public static long getRealSizeOnPhone() {
		File path = Environment.getDataDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long availableBlocks = stat.getAvailableBlocks();
		long realSize = blockSize * availableBlocks;
		return realSize;
	}
	
	
//	1、apk中有两种资源文件，使用两种不同的方式进行打开使用。
//	raw使用InputStream in = getResources().openRawResource(R.raw.test);
//	asset使用InputStream in = getResources().getAssets().open(fileName);
//	这些数据只能读取，不能写入。更重要的是该目录下的文件大小不能超过1M。
//	同时，需要注意的是，在使用InputStream的时候需要在函数名称后加上throws IOException。
	
//	2、SD卡中的文件使用FileInputStream和FileOutputStream进行文件的操作。
	
//	3、存放在数据区(/data/data/..)的文件只能使用openFileOutput和openFileInput进行操作。
//	注意不能使用FileInputStream和FileOutputStream进行文件的操作。
	
//	4、RandomAccessFile类仅限于文件的操作，不能访问其他IO设备。它可以跳转到文件的任意位置，从当前位置开始读写。
	
//	5、InputStream和FileInputStream都可以使用skip和read(buffre,offset,length)函数来实现文件的随机读取
	
	
	
}

